package com.zhny.protocol_v3_008.creator;

import java.util.TreeMap;
import java.util.zip.CRC32;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.zhny.protocol_v3_008.constant.PackageType;
import com.zhny.protocol_v3_008.model.Datagram;

import com.zhny.service.JsonBuilder;
import com.zhny.util.ArrayUtils;
import com.zhny.util.BytesUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author Create By Alex On 2017年11月9日 下午10:17:32
 */

@Component
public class PackageCreator {

    @Autowired
    private JsonBuilder jsonBuilder;
    /**
     *
     * @param datagram 需要转化成字节的数据报
     * @return 字节数组
     */
    public byte[] createPackage(Datagram datagram) {
        byte[] dataPackage = null;
        if (datagram != null) {
            byte[] head = BytesUtils.getBytes(datagram.getHead());
            byte[] packageType = BytesUtils.getBytes(datagram.getPackageType());
            byte[] date = BytesUtils.getBytes(datagram.getDate());
            byte[] deviceFlag = BytesUtils.getBytes(datagram.getDeviceFlag());
            byte[] deviceType = BytesUtils.getBytes(datagram.getDeviceType());
            byte[] dataLength = BytesUtils.getBytes(datagram.getDataLength());
            byte[] data = BytesUtils.getBytes(datagram.getData());
            byte[] code = ArrayUtils.concatAll(packageType, date, deviceFlag, deviceType, dataLength, data);
            byte[] crc = BytesUtils.getBytes(createCRC32(code,datagram));
            byte[] end = BytesUtils.getBytes(datagram.getEnd());
            dataPackage = ArrayUtils.concatAll(head, code, crc, end);
        }
        return dataPackage;
    }

    /**
     * @param b 需要进行CRC32校验的字节
     * @return crc32校验码
     */
    private int createCRC32(byte[] b,Datagram datagram) {
        CRC32 crc = new CRC32();
        crc.update(b);
        long code = crc.getValue();
        datagram.setCrc(code);
        return (int) code;
    }

    /**
     *
     * @param deviceFlag 设备标识
     * @param deviceType 设备类型
     * @return 遥测数据报
     */
    public Datagram createTelemeterDatagram(Integer deviceFlag, Short deviceType) throws JsonProcessingException {
        String json = jsonBuilder.buildJsonFromService(deviceFlag);
        Datagram datagram = new Datagram(PackageType.TELEMETRY,deviceFlag,deviceType);
        datagram.setData(json);
        return datagram;
    }

    /**
     * 发送单一站点的注册信息
     * @param deviceFlag 设备标识
     * @param deviceType 设备类型
     * @return 注册数据报
     */
    public Datagram createRegisterDatagram(Integer deviceFlag, Short deviceType) {
        String value = "{\"" + deviceFlag + "\":" + deviceType + "}";
        Datagram datagram = new Datagram(PackageType.REGISTER, deviceFlag, deviceType);
        datagram.setData(value);
        return datagram;
    }

    /**
     * 发送多站点的注册信息
     * @param deviceTable {deviceFlag:deviceType}
     * @return 注册数据报
     */
    public Datagram createRegisterDatagram(TreeMap<Integer, Short> deviceTable) throws JsonProcessingException {
        int deviceFlag = deviceTable.firstKey();
        short deviceType = deviceTable.firstEntry().getValue();
        if (deviceTable.size() == 0)
            throw new NullPointerException();
        else if (deviceTable.size() == 1) {
            return createRegisterDatagram(deviceFlag, deviceType);
        }
        Datagram datagram = new Datagram(PackageType.REGISTER, deviceFlag, deviceType);
        datagram.setData(jsonBuilder.buildJson(deviceTable));
        return datagram;
    }

    /**
     * 创建心跳数据包
     * @param deviceTable {deviceFlag:deviceType}
     * @return 心跳数据报
     */
    public Datagram createHearBeatDatagram(TreeMap<Integer, Short> deviceTable) throws JsonProcessingException {
        int deviceFlag = deviceTable.firstKey();
        short deviceType = deviceTable.firstEntry().getValue();
        Datagram heartBeatDatagram = new Datagram(PackageType.HEART,deviceFlag,deviceType);
        heartBeatDatagram.setData(jsonBuilder.buildJson(deviceTable));
        return heartBeatDatagram;
    }

}
